/************************************************************************
This file is part of java core libraries for the simpleRTJ virtual machine.

This file is covered by the GNU GPL with the following exception:
  As a special exception, the copyright holders of this library give you permission
  to link this library with independent modules to produce an executable, regardless
  of the license terms of these independent modules, and to copy and distribute the
  resulting executable under terms of your choice, provided that you also meet, for
  each linked independent module, the terms and conditions of the license of that
  module. An independent module is a module which is not derived from or based on
  this library. If you modify this library, you may extend this exception to your
  version of the library, but you are not obligated to do so. If you do not wish
  to do so, delete this exception statement from your version.


THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL RTJ COMPUTING BE LIABLE FOR ANY CLAIM, DAMAGES
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

Copyright (c) 2000-2002 RTJ Computing Pty. Ltd. All rights reserved.
***********************************************************************/
package javax.events;

import java.lang.*;

/**
 * Base class for all asynchronous events. Can be subclassed to implement event specific
 * processing.
 */
public class AsyncEvent
{
    /**
     * Holds references to event handlers.
     */
    protected AsyncEventHandler evHandlers[];

    /**
     * AsyncEvent constructor that creates an array of handleres that can hold just
     * one event hander. This is the default constructor for majority asynch events.
     */
    public AsyncEvent()
    {
        evHandlers = new AsyncEventHandler[1];
    }

    /**
     * AsyncEvent constructor that creates an array of handleres that can hold specified number
     * of event handers.
     * @param count     max. number of handlers that can be associated with this event.
     */
    public AsyncEvent(int count)
    {
        evHandlers = new AsyncEventHandler[count];
    }

    /**
     * Adds a new AsyncEventHandler to the current list of handlers.
     * @param handler       reference to asynchronous event handler
     * @return An ID of the handler if successful, otherwise -1 is returned.
     * @exception HandlerLimitException thrown if there are no more timers available
     */
    public int addHandler(AsyncEventHandler handler) throws HandlerLimitException
    {
        for (int i=0; i < evHandlers.length; i++)
        {
            if (evHandlers[i] == null)
            {
                evHandlers[i] = handler;
                return i;
            }
        }
        throw new HandlerLimitException();
    }

    /**
     * Retrieves AsyncEventHandler at specified index.
     * @param index       index of asynchronous event handler to be retrieved
     * @return Reference to the handler if successful, otherwise null is returned.
     */
    public AsyncEventHandler getHandler(int index)
    {
        if (index < evHandlers.length)
            return evHandlers[index];
        return null;
    }

    /**
     * Checks if the specified handler has been added into event handlers list.
     * @param handler       reference to asynchronous event handler
     * @return true if handler is already present in the event handlers list,
     *         otherwise false is returned.
     */
    public boolean handledBy(AsyncEventHandler handler)
    {
        for (int i=0; i < evHandlers.length; i++)
        {
            if (evHandlers[i] != null && handler == evHandlers[i])
                return true;
        }
        return false;
    }

    /**
     * Removes specified handler from the list of event handlers.
     * @param handler       reference to asynchronous event handler
     */
    public void removeHandler(AsyncEventHandler handler)
    {
        for (int i=0; i < evHandlers.length; i++)
        {
            if (evHandlers[i] != null && handler == evHandlers[i])
                evHandlers[i] = null;
        }
    }

    /**
     * Removes all handlers from the handlers list and sets the handleras current.
     * @param handler       reference to asynchronous event handler
     */
    public void setHandler(AsyncEventHandler handler)
    {
        for (int i=0; i < evHandlers.length; i++)
            evHandlers[i] = null;

        evHandlers[0] = handler;
    }

    /**
     * Method called by the event dispatcher (Events class). Body must be
     * implemented by all asynch events registered in Events class.<p>
     * Calls handleAsyncEvent() method for each registered event handler.
     */
    public void fire()
    {
        for (int i=0; i < evHandlers.length; i++)
        {
            if (evHandlers[i] != null)
                evHandlers[i].handleAsyncEvent();
        }
    }
}


